home *** CD-ROM | disk | FTP | other *** search
/ Gigarom 1 / Gigarom Macintosh Archives (Quantum Leap)(CDRM1080320)(1993).iso / FILES / DEV / I-Z / TransSkel.cpt / MSkelZoom.pas < prev    next >
Pascal/Delphi Source File  |  1987-01-07  |  5KB  |  207 lines

  1. {    TransSkel multiple-window demonstration: ZoomRect module}
  2.  
  3. {    This module handles a window in which successive randomly generated}
  4. {    rectangles are smoothly interpolated into one another.  The display}
  5. {    is white on black, which results in some interesting problems (see}
  6. {    ZDrawGrowBox, for instance).  The display adjusts itself to the size}
  7. {    of the window, so that the zoom series always lie entirely within}
  8. {    the window.  Clicking the mouse in the window pauses the display until}
  9. {    the button is released.}
  10.  
  11. {    14 June 1986        Paul DuBois}
  12. {    7 January 1987    ported to LightSpeed Pascal by Owen Hartnett            }
  13. {    Ωhm Software Company.                                                    }
  14.  
  15.  
  16. UNIT MSkelZoom;
  17.  
  18. INTERFACE
  19.  
  20.     USES
  21.         MultiSkelGlobs, common, TransSkelpas;
  22.  
  23.     PROCEDURE ZoomWindInit;
  24.  
  25. IMPLEMENTATION
  26.  
  27.  
  28.     CONST
  29.         zoomSteps = 15;        { # rects in interpolative series }
  30.  
  31.     VAR
  32.         zRect : ARRAY[0..zoomSteps] OF Rect;        { set of interpolated rectangles }
  33.         zSrcRect : Rect;
  34.         sizeX, sizeY : integer;                { size of window in pixels }
  35.  
  36.     PROCEDURE SetZoomSize;
  37.  
  38.         VAR
  39.             r : Rect;
  40.  
  41.     BEGIN
  42.         r := zoomWind^.portRect;
  43.         r.right := r.right - 15;                { don't use right edge }
  44.         sizeX := r.right;
  45.         sizeY := r.bottom;
  46.     END;
  47.  
  48. {    return integer between zero and max (inclusive).  assumes max is}
  49. {    non-negative.}
  50.  
  51.     FUNCTION Rand (max : integer) : integer;
  52.  
  53.         VAR
  54.             t : integer;
  55.  
  56.     BEGIN
  57.         t := Random;
  58.         IF (t < 0) THEN
  59.             t := -t;
  60.         Rand := t MOD (max + 1);
  61.     END;
  62.  
  63. {    Interpolate one rectangle smoothly into another.  Erase the previous}
  64. {    series as the new one is drawn.}
  65.  
  66.     PROCEDURE zoomRect (r1, r2 : Rect);
  67.  
  68.         VAR
  69.             r1left, r1top : integer;
  70.             l, t : integer;
  71.             j : integer;
  72.             hDiff, vDiff, widDiff, htDiff : integer;
  73.             r, b : integer;
  74.             rWid, rHt : integer;
  75.  
  76.     BEGIN
  77.         r1left := r1.left;
  78.         r1top := r1.top;
  79.         hDiff := r2.left - r1left;        {positive if moving to right }
  80.         vDiff := r2.top - r1top;        {positive if moving down        }
  81.  
  82.         rWid := r1.right - r1left;
  83.         rHt := r1.bottom - r1top;
  84.         widDiff := (r2.right - r2.left) - rWid;
  85.         htDiff := (r2.bottom - r2.top) - rHt;
  86.  
  87. {    order of evaluation is important in the rect coordinate calculations.}
  88. {    since all arithmetic is integer, you can't save time by calculating}
  89. {    j/zoomSteps and using that - it'll usually be zero.}
  90.  
  91.         FOR j := 1 TO zoomSteps DO
  92.             BEGIN
  93.                 FrameRect(zRect[j - 1]);                { erase a rectangle }
  94.                 l := r1left + (hDiff * j) DIV zoomSteps;
  95.                 t := r1top + (vDiff * j) DIV zoomSteps;
  96.                 r := l + rWid + (widDiff * j) DIV zoomSteps;
  97.                 b := t + rHt + (htDiff * j) DIV zoomSteps;
  98.                 SetRect(zRect[j - 1], l, t, r, b);
  99.                 FrameRect(zRect[j - 1]);
  100.             END;
  101.     END;
  102.  
  103.     PROCEDURE Idle;
  104.  
  105.         VAR
  106.             i : integer;
  107.             pt1, pt2 : Point;
  108.             dstRect : Rect;
  109.  
  110.     BEGIN
  111.         SetPt(pt1, Rand(sizeX), Rand(sizeY));    { generate new rect }
  112.         SetPt(pt2, Rand(sizeX), Rand(sizeY));    { and zoom to it        }
  113.         Pt2Rect(pt1, pt2, dstRect);
  114.         SetWindClip(zoomWind);            { don't draw in right edge }
  115.         ZoomRect(zSrcRect, dstRect);
  116.         ResetWindClip;
  117.         zSrcRect := dstRect;
  118.     END;
  119.  
  120. {    just pause zoom display while mouse down}
  121.  
  122.     PROCEDURE Mouse (thePt : point;
  123.                                     t : longint;
  124.                                     mods : integer);
  125.     BEGIN
  126.         WHILE (StillDown) DO
  127.             ;  { wait until mouse button released }
  128.     END;
  129.  
  130. {    Draw the grow box in white on black.  This is tricky:  if the window}
  131. {    is inactive, the grow box will be drawn black, as it should be.  But}
  132. {    if the window is active, the box will STILL be drawn black on white!}
  133. {    So have to check whether the window is active or not.  The test for}
  134. {    active has to be done carefully:  the window manager stores 255 and 0}
  135. {    for true and false, not real boolean values.}
  136.  
  137.     PROCEDURE ZDrawGrowBox;
  138.         VAR
  139.             r : Rect;
  140.             zoomPeek : WindowPeek;
  141.  
  142.     BEGIN
  143.         PenMode(notPatCopy);
  144.         DrawGrowBox(zoomWind);
  145.         PenMode(patXor);
  146.         zoomPeek := WindowPeek(zoomWind);
  147.         IF (zoomPeek^.hilited) THEN    { grow box draw in white }
  148.             BEGIN                        { no matter what if active }
  149.                 r := zoomWind^.portRect;                { - invert to fix }
  150.                 r.left := r.right - 14;
  151.                 r.top := r.bottom - 14;
  152.                 InvertRect(r);
  153.             END;
  154.     END;
  155.  
  156.     PROCEDURE Update (resized : Boolean);
  157.  
  158.         VAR
  159.             i : integer;
  160.     BEGIN
  161.         EraseRect(zoomWind^.portRect);
  162.         ZDrawGrowBox;
  163.         SetWindClip(zoomWind);
  164.         FOR i := 0 TO zoomSteps - 1 DO
  165.             FrameRect(zRect[i]);
  166.         ResetWindClip;
  167.         IF resized THEN
  168.             SetZoomSize;    { adjust to new window size }
  169.     END;
  170.  
  171.     PROCEDURE Activate (active : Boolean);
  172.  
  173.     BEGIN
  174.         ZDrawGrowBox;
  175.         IF active THEN
  176.             DisableItem(editMenu, 0)
  177.         ELSE
  178.             EnableItem(editMenu, 0);
  179.         DrawMenuBar;
  180.     END;
  181.  
  182.     PROCEDURE Halt;
  183.     BEGIN
  184.         CloseWindow(zoomWind);
  185.     END;
  186.  
  187.     PROCEDURE ZoomWindInit;
  188.  
  189.         VAR
  190.             i : integer;
  191.     BEGIN
  192.         zoomWind := GetNewWindow(zoomWindRes, NIL, WindowPtr(-1));
  193.         SkelWindow(zoomWind, @Mouse, NIL, @Update, @Activate, NIL, @Halt, @Idle, true);
  194.             { ignore key clicks }
  195.             { no close proc }
  196.         { when done with window }
  197.         { draw a new series }
  198.             { run only when frontmost }
  199.  
  200.         SetZoomSize;
  201.         BackPat(black);
  202.         PenMode(patXor);
  203.         SetRect(zSrcRect, 0, 0, 0, 0);
  204.         FOR i := 0 TO zoomSteps - 1 DO        { initialize rect array }
  205.             zRect[i] := zSrcRect;
  206.     END;
  207. END.